//==============================================================================
// Code to log data to a file in the plugins directory
//==============================================================================

#include "MP.h"


//==============================================================================
// Function to open the log file
//==============================================================================
int __stdcall MP_open_log()
{  char str[120];
   time_t time_since;
   struct tm * cur_time;

   time( &time_since );                                            // get the time 
   cur_time =localtime( &time_since );                             // convert to local time
   strftime(str, sizeof str, "%d/%m/%y %H:%M:%S", cur_time );  

   if ((fp_log=fopen("plugins\\MP.log","w"))==NULL) { printf("Failed to open log file"); return 0; }  
   fprintf(fp_log,"*********************************************************************\n");
   fprintf(fp_log,"MediaPortal LCDSmartie Plugin by Dave Perrow 8th March 2012\n");
   fprintf(fp_log,"%s version %s\n",FILE_DESCRIPTION,VER_STRING);
   fprintf(fp_log,"Log file Opened at %s\n",str);
   fprintf(fp_log,"*********************************************************************\n");
   fflush(fp_log);
   MP_log("Log file Opened at",str);
}


//==============================================================================
// Function to close the log file
//==============================================================================
extern int __stdcall MP_close_log() 
{  char str[120];
   time_t time_since;
   struct tm * cur_time;

   time( &time_since );   // get the time 
   cur_time =localtime( &time_since );  // convert to local time
   strftime(str, sizeof str, "%d/%m/%y %H:%M:%S", cur_time );  

   fprintf(fp_log,"*********************************************************************\n");
   fprintf(fp_log,"MediaPortal LCDSmartie Plugin by Dave Perrow 8th March 2012\n");
   fprintf(fp_log,"%s version %s\n",FILE_DESCRIPTION,VER_STRING);
   fprintf(fp_log,"Log file Closed at %s\n",str);
   fprintf(fp_log,"*********************************************************************\n");
   fflush(fp_log);
   fclose(fp_log); 
   fp_log=NULL;
} 

//==============================================================================
// Function to Log some text to the log file 
// in the form: hh:mm:ss 23/07/11 <Module_Name> <Text>
//==============================================================================
int __stdcall MP_log_it(int level, char * module, char * msg, int writeit)
{  time_t time_since;
   struct tm * cur_time;
   struct _timeb timebuffer;
   char log_time[120];
   char line[MAX_STRING*2],timebit[MAX_STRING];
   int i;
   
   _ftime( &timebuffer );
   time( &time_since );   // get the time 
   cur_time =localtime( &time_since );  // convert to local time
   strftime(log_time, sizeof log_time, "%H:%M:%S", cur_time );  
   sprintf(timebit,"%s.%03hu %s ",log_time,timebuffer.millitm,module);
   strcpy(line,timebit);
   i=strlen(msg); if (i>MAX_LOGTEXT-1) i=MAX_LOGTEXT-1;
   strncat(line,msg,i);
   i=strlen(line); if (i>MAX_LOGTEXT-1) i=MAX_LOGTEXT-1;
   strncpy(MP_log_cache[MP_log_cache_ptr].text,line,i);
   MP_log_cache[MP_log_cache_ptr].text[i]=0;
   MP_log_cache[MP_log_cache_ptr].used=1;
   MP_log_cache_ptr=MP_log_cache_ptr+1;
   if (MP_log_cache_ptr>MAX_LOG_CACHE) MP_log_cache_ptr=0; // points to next available entry

   if ((writeit!=0)  ||  (MP_Global_Debug>=level))
     { if (fp_log!=NULL)
         { fprintf(fp_log,"%s%s\n",timebit,msg);
           fflush(fp_log);
         }
     }
}

//==============================================================================
// Function to Log some text to the log file if the debug flag is set 
//==============================================================================
extern int __stdcall MP_log(char * module, char * msg)
{  MP_log_it(1,module,msg,MP_Global_Debug); }

//==============================================================================
// Function to Log some text to the log file if the debug flag is set 
//==============================================================================
extern int __stdcall MP_logl(int level, char * module, char * msg)
{  MP_log_it(level,module,msg,0); }

//==============================================================================
// Function to Log some text to the log file if the debug flag is set 
//==============================================================================
extern int __stdcall MP_errlog(char * module, char * msg)
{ int i,j; char str[256];

  if (fp_log==NULL) MP_open_log();
  j=MP_log_cache_ptr;
  if (MP_Global_Debug==0)
    { for (i=0;i<MAX_LOG_CACHE;i++)
        { if (MP_log_cache[j].used==1) 
            { fprintf(fp_log,"%s\n",MP_log_cache[j].text);
              MP_log_cache[j].used=0;
            }
          j=j+1; if(j>MAX_LOG_CACHE) j=0;
        }
      fflush(fp_log);
    }

  strcpy(str,"**Error**"); strcat(str,module);
  MP_log_it(0,str,msg,1);
}


//==============================================================================
// Locking routines - should used around access to the tag data structure but 
// probably not at the put/get level which would be too much of an overhead.
//==============================================================================
static int lock_initialised=0;
HANDLE ghSemaphore;

// SRWLOCK MYLock;			// Lock


//==============================================================================
// Lock routine
//==============================================================================
extern void __stdcall MP_lock()
{  DWORD dwWaitResult; char str[80];

   if (lock_initialised==0)
     {   
//        InitializeSRWLock(&MYLock);
        // Create a semaphore with initial and max counts of MAX_SEM_COUNT
        ghSemaphore = CreateSemaphore( NULL,           // default security attributes
                                       MAX_SEM_COUNT,  // initial count
                                       MAX_SEM_COUNT,  // maximum count
                                       NULL);          // unnamed semaphore
        if (ghSemaphore == NULL) { sprintf(str," %d",GetLastError()); MP_errlog("MP_Lock:",str); return; }  // 
     }
   lock_initialised=1;
//   AcquireSRWLockExclusive(&MYLock);
   dwWaitResult = WaitForSingleObject( ghSemaphore,INFINITE );
}

//==============================================================================
// Unlock routine
//==============================================================================
extern void __stdcall MP_unlock()
{ char str[80];

  if (!ReleaseSemaphore( ghSemaphore,  // handle to semaphore
                         1,            // increase count by one
                         NULL) )       // not interested in previous count
                {  sprintf(str,"ReleaseSemaphore error: %d\n", GetLastError()); MP_errlog("MP_unlock",str); }
//  ReleaseSRWLockExclusive(&MYLock);
}
